Skip to content

🐛(i18n/backend) Fix/email in receiving user language #401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

rvveber
Copy link
Collaborator

@rvveber rvveber commented Nov 4, 2024

Implements the following:

  • E-mails sent for granting access are sent in the users language if it exists - else they will be sent in system default language
  • On Language change in the frontend, the language attribute of the user is updated via API.
  • Fixes to language related Tests
  • Added helper for language related Tests

Closes #323

@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch 2 times, most recently from c645b5b to 72b5272 Compare November 4, 2024 14:10
@rvveber rvveber marked this pull request as draft November 4, 2024 14:27
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch 4 times, most recently from 62ebf55 to 332e770 Compare November 18, 2024 17:20
@rvveber
Copy link
Collaborator Author

rvveber commented Nov 21, 2024

@sampaccoud
Would it make sense to refactor the backend user.language choices to ISO639-1?
eg. fr-fr -> fr

@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch 6 times, most recently from fef3dea to 3b3e90c Compare November 21, 2024 16:46
@rvveber rvveber requested review from AntoLC and sampaccoud November 21, 2024 16:55
@rvveber rvveber marked this pull request as ready for review November 21, 2024 16:56
Copy link
Collaborator

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good !
A few comments.

@sampaccoud Should we add a migration to make all our current users french by default, because they will all switch to english after that, wdyt ?

@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch 2 times, most recently from b3534d3 to 704550b Compare November 25, 2024 14:50
@rvveber rvveber requested a review from AntoLC November 25, 2024 14:51
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch from 704550b to d9bad8c Compare November 25, 2024 14:53
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch from d9bad8c to f773350 Compare November 27, 2024 14:30
@rvveber rvveber requested a review from AntoLC November 27, 2024 14:32
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch 2 times, most recently from 1b5eb7b to 38639c9 Compare November 27, 2024 14:44
Copy link
Collaborator

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Good job, works perfect ^^

I think Sam wants to have a look at it before merging.

@sampaccoud
Copy link
Member

I was expecting the language to be set on the user on first logging here:
https://github.com/numerique-gouv/impress/blob/main/src/backend/core/authentication/backends.py#L91

Otherwise how and when is this field set on the user? 🤔

@rvveber rvveber requested a review from AntoLC February 25, 2025 19:45
Copy link
Collaborator

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments but it seems good to me, all seems working fine.

We try to not mix backend and frontend in the same commit, to be easier for reviewers, some of us are specialized in backend, other in front.

Comment on lines 140 to 146
const [response] = await Promise.all([
page.waitForResponse(
(resp) =>
resp.url().includes('/user') && resp.request().method() === 'PATCH',
),
page.getByLabel(lang.label).click(),
]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const [response] = await Promise.all([
page.waitForResponse(
(resp) =>
resp.url().includes('/user') && resp.request().method() === 'PATCH',
),
page.getByLabel(lang.label).click(),
]);
const response = page.waitForResponse(
(resp) =>
resp.url().includes('/user') && resp.request().method() === 'PATCH',
);
await page.getByLabel(lang.label).click();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +26 to 43
const defaultQueries = [
{
icon: 'apps',
label: t('All docs'),
targetQuery: DocDefaultFilter.ALL_DOCS,
},
{
icon: 'lock',
label: t('My docs'),
targetQuery: DocDefaultFilter.MY_DOCS,
},
{
icon: 'group',
label: t('Shared with me'),
targetQuery: DocDefaultFilter.SHARED_WITH_ME,
},
];

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of useMemo is dicutable, but is this change necessary ? It seems to work correctly on my side.

Copy link
Collaborator Author

@rvveber rvveber Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function t was not changing, when language was updated automatically to whatever is defined on the user.
Not sure why it happens, seems to be an issue of async nature.

Here is how you can reproduce it:

  1. Switch back to the variant with useMemo
  2. Log in to django backend.
  3. Go to frontend (new tab)
  4. Change language to french
    image
  5. Go to django backend and change superusers language to any other eg. deutsch
    image
  6. Switch back to frontend tab and reload
    image
  7. Left panel still has old translation

Comment on lines 109 to 112
test.afterEach(async ({ page }) => {
// Switch back to English - important for other tests to run as expected
await waitForLanguageSwitch(page, TestLanguage.English);
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add it to the top ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -41,7 +41,10 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
<QueryClientProvider client={queryClient}>
<CunninghamProvider theme={theme}>
<ConfigProvider>
<Auth>{children}</Auth>
<Auth>
<LanguageInitializer />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add it in the ConfigProvider, it seems more appropriate.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure?
I need auth to access the language of the user, logic in ConfigProvider does not need auth (yet)

It will add quite a bit of bloat to the ConfigProvider, better to have everything encapsulated in components and use them where they are needed right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can work if i make LanguageInitializer an async hook as you suggested below.
working on it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,66 @@
import i18n from 'i18next';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to get it like that:

import { useTranslation } from 'react-i18next';
...
const { i18n } = useTranslation();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


import { getMatchingLocales } from './utils/locale';

const LanguageInitializer = () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the component doesn't have any content, better to make it as a hook, wdyt ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch 3 times, most recently from ffe4ad4 to 40d8831 Compare March 4, 2025 09:30
@rvveber rvveber marked this pull request as draft March 4, 2025 10:26
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch from 40d8831 to a313c91 Compare March 4, 2025 15:13
rvveber added 2 commits March 4, 2025 16:14
- language for invitation emails => language saved on the invited user
- if invited user does not exist yet => language of the sending user
- if for some reason no sending user => system default language
- language for invitation emails => language saved on the invited user
- if invited user does not exist yet => language of the sending user
- if for some reason no sending user => system default language
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch from a313c91 to 70704d7 Compare March 4, 2025 15:31
@rvveber rvveber marked this pull request as ready for review March 4, 2025 15:31
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch from 70704d7 to b0a5b71 Compare March 4, 2025 15:37
rvveber added 10 commits March 4, 2025 16:40
- allow the language on the user to be unset
- set the default language to be unset
- helps us determine that the user has yet to set a language preference
- allow the language attribute on the user to be updated via API
- add frontend function to update the user language via API
- extend defaults on the test users, to have fixed language in E2E tests
- extend types and variables using the types with the new field
- allow the language attribute on the user to be updated via API
- add frontend function to update the user language via API
- extend defaults on the test users, to have fixed language in E2E tests
- extend types and variables using the types with the new field
- Adds a helper for working with locales
- More details in their annotations
- Unnecessary, if in the future, the backend uses
  the same locales as the keys in the translations (ISO 639-1)
- config endpoint languages are used as available options for LanguagePicker
- updating the language from it, triggers an update on the user via API
- config endpoint languages are used as available options for LanguagePicker
- updating the language from it, triggers an update on the user via API
- ensure editor is translated to i18n.resolvedLanguage => en
  as i18n.language could hold more accurate locale => en-GB etc..
- adds useLanguageSynchronizer hook to update the:
  1. frontend-language to the user-preference - if there is one.
  2. user-preference to the (browser-detected) frontend-language - otherwise.
- fixes a bug where after language-sync the left panel would remain
  in the same language as before.
- adds tests and test-utility for solid language switching in tests
- fixes where ...getByRole(menuitem... would not return a valid object
@rvveber rvveber force-pushed the fix/email-in-receiving-user-language branch from b0a5b71 to 2419c26 Compare March 4, 2025 15:41
@virgile-dev
Copy link
Collaborator

@sampaccoud could you approve and merge ?

@sampaccoud
Copy link
Member

@rvveber Amazing fix! Thanks for that Robin 💪 🎉

@sampaccoud sampaccoud enabled auto-merge (rebase) March 5, 2025 13:17
@sampaccoud sampaccoud merged commit 251787b into suitenumerique:main Mar 5, 2025
17 of 18 checks passed
@AntoLC AntoLC mentioned this pull request Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Receive email notification in my language
4 participants